package in.ac.dei.edrp.cms.daoimpl.registration.prestagingdaoimpl;



import java.util.ArrayList;
import java.util.List;

import javax.imageio.spi.RegisterableService;

import org.apache.log4j.Logger;
import org.springframework.orm.ibatis.SqlMapClientTemplate;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;
import org.springframework.transaction.support.TransactionTemplate;

import com.ibatis.sqlmap.client.SqlMapClient;

import in.ac.dei.edrp.cms.constants.CRConstant;
import in.ac.dei.edrp.cms.daoimpl.activitymaster.StartActivityDaoImpl;
import in.ac.dei.edrp.cms.domain.activitymaster.CountProcessRecorList;
import in.ac.dei.edrp.cms.domain.activitymaster.StartActivityBean;
import in.ac.dei.edrp.cms.domain.registration.prestaging.ActivityMasterBean;

import in.ac.dei.edrp.cms.domain.registration.prestaging.ProcessList;
import in.ac.dei.edrp.cms.domain.registration.prestaging.TransferNORInPSTBean;
import in.ac.dei.edrp.cms.domain.utility.ErrorLogs;
import in.ac.dei.edrp.cms.domain.utility.StudentTracking;
import in.ac.dei.edrp.cms.utility.PreviousSemesterDetail;
import in.ac.dei.edrp.cms.utility.RegistrationFunction;
import in.ac.dei.edrp.cms.utility.StudentTrackingFunction;


/**
 * This class transfers student in PreStaging with appropriate semester.
 * It transfers student for 3 cases: PASS, FAIL, REMEDIAL
 * PAS: Moves to next semester
 * FAL: Moves to semester code (minimum sequence number of UIP.semester group)
 * REM: Moves to next semester with probable entries.
 * If there is not attempt number and student is fail, then registration semester will be undefined. 
 * @author Deepak
 *
 */
public class TransfertNORInPSTFunction{
	
	static final Logger logger = Logger.getLogger(TransfertNORInPSTFunction.class);
	
	protected SqlMapClient sqlMapClient = null;
	
    public void setSqlMapClient(SqlMapClient sqlMapClient) {
        this.sqlMapClient = sqlMapClient;
    }
	
	
    TransactionTemplate transactionTemplate=null;

	public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
		this.transactionTemplate = transactionTemplate;
	}
	
	
	public TransfertNORInPSTFunction(SqlMapClient sqlMapClient,
			TransactionTemplate transactionTemplate) {
		super();
		this.sqlMapClient = sqlMapClient;
		this.transactionTemplate = transactionTemplate;
	}

	public TransfertNORInPSTFunction() {
		super();
		
	}
	
	/**
	 * @param activityMasterBean
	 * returns true if all records processed successfully else false
	 */
	public CountProcessRecorList transferNorinPST(ActivityMasterBean activityMasterBean) {
		// TODO Auto-generated method stub
		RegistrationFunction registrationFunction=new RegistrationFunction(sqlMapClient,transactionTemplate);
		PreStagingTransactionFunction preStagingTransactionFunction=
			new PreStagingTransactionFunction(sqlMapClient,transactionTemplate);
		
		CountProcessRecorList countList=new CountProcessRecorList();
		
		ErrorLogs errorLogs=new ErrorLogs(activityMasterBean.getEntityId(),activityMasterBean.getProgramId(),
				activityMasterBean.getBranchId(),activityMasterBean.getSpecializationId(),
				activityMasterBean.getSemesterCode(),activityMasterBean.getSemesterStartDate(),activityMasterBean.getSemesterEndDate(),
				activityMasterBean.getProcessId(),activityMasterBean.getActivityId());
		
		int actualRecords=0;
		int processedStudent=0;
		int recordsFailed=0;
		int rejectedValue=0;
		
		boolean processedFlag=false;
		List<TransferNORInPSTBean> studentProgramList=new ArrayList<TransferNORInPSTBean>();
		
		try{
			String universityId=activityMasterBean.getUniversityId();
			
			String entityId=activityMasterBean.getEntityId();
			String programId=activityMasterBean.getProgramId();
			String branchId=activityMasterBean.getBranchId();
			String specializationId=activityMasterBean.getSpecializationId();
			String semesterCode=activityMasterBean.getSemesterCode();
			String semesterStartDate=activityMasterBean.getSemesterStartDate();
			String semesterEndDate=activityMasterBean.getSemesterEndDate();
			String status=activityMasterBean.getStatus();	
			
			String sessionStartDate=activityMasterBean.getSessionStartDate();
			String sessionEndDate=activityMasterBean.getSessionEndDate();
			
			String activityId=activityMasterBean.getActivityId();
		
//			 int processCounter=new StudentTrackingFunction(sqlMapClient,transactionTemplate).batchProcessExist(errorLogs);
//			 errorLogs.setProcessCounter(processCounter+1);
//			 sqlMapClient.insert("studentTrackingAndLogs.insertBatchLogs",errorLogs);
			 
			String creatorId=activityMasterBean.getUserId();
			
//			System.out.println(entityId+"="+programId+"="+branchId+"="+specializationId+"="+semesterCode+""
//					+"="+semesterStartDate+"="+semesterEndDate+"="+status);
			
			TransferNORInPSTBean userData=new TransferNORInPSTBean(entityId,programId,branchId,
					specializationId,semesterCode,semesterStartDate,
					semesterEndDate);
			
			//All System.out.println statements will be removed after testing or before SVN commit
			//System.out.println("Coming before query:"+userData.getSemesterCode()+" and "+userData.getProgramId());
			
			//pick up previous semester code and group
			List<TransferNORInPSTBean> registerSemesterList=(List<TransferNORInPSTBean>)sqlMapClient.queryForList("TransferNORInPSTBean.getNextSemester",userData);
//			System.out.println("Coming after query:"+registerSemesterList.size());
			
			String registerSemester="";
			String registerStartDay="";
			String registerEndDay="";
			boolean checkGroup=false;
			
			for(TransferNORInPSTBean registerSemesterCode:registerSemesterList){
				registerSemester=registerSemesterCode.getNextSemesterCode();
				checkGroup=registerSemesterCode.getCheckSemesterGroup();
				registerStartDay=registerSemesterCode.getSemesterStartDate();
				registerEndDay=registerSemesterCode.getSemesterEndDate();
				
//				System.out.println(checkGroup+"="+registerStartDay+"="+registerEndDay);
			}
			
			//System.out.println("Previous semester is: "+registerSemester+" and group="+checkGroup);
			
			//Pick up program course key for User input
			TransferNORInPSTBean userkeyData=new TransferNORInPSTBean(programId,branchId,specializationId,semesterCode);			
			String programCourseKey=registrationFunction.getProgramCourseKey(userkeyData);
			//System.out.println("registration program course key: "+programCourseKey);
			
			//Pick up program course key for registration semester if student is PASS
			TransferNORInPSTBean registerKeyData=new TransferNORInPSTBean(programId,branchId,specializationId,registerSemester);			
			String registerProgramCourseKey=registrationFunction.getProgramCourseKey(registerKeyData);
			//System.out.println("registration program course key: "+registerProgramCourseKey);
			
//			String registerSemesterStartDate=registrationFunction.getActualRegisterDate(registerStartDay);
//			String registerSemesterEndDate=registrationFunction.getActualRegisterDate(registerEndDay);
			String registerSemesterStartDate="";
			String registerSemesterEndDate="";
			
			//For getting registration start and end date for PAS and remedial stduent
			//It gets date according to active session and registration program course key
			TransferNORInPSTBean datesData=new TransferNORInPSTBean(registerProgramCourseKey,activityMasterBean.getSessionStartDate(),
					activityMasterBean.getSessionEndDate());
			List<TransferNORInPSTBean> startEndDate=sqlMapClient.queryForList("TransferNORInPSTBean.getYTRDate",datesData);
			for(TransferNORInPSTBean registerdates:startEndDate){
				registerSemesterStartDate=registerdates.getSemesterStartDate();
				registerSemesterEndDate=registerdates.getSemesterEndDate();
//				System.out.println(registerSemesterEndDate+registerSemesterStartDate);
			}
			
//			System.out.println("Yes"+registerSemesterStartDate+" and "+registerSemesterEndDate);
			//Register due date for registration semester
			TransferNORInPSTBean registerDueDateData=new TransferNORInPSTBean(registerProgramCourseKey, registerSemesterStartDate, registerSemesterEndDate);
			String registerDueDate=registrationFunction.getRegisterDueDate(registerDueDateData);
			//System.out.println("registration start date: "+registerDueDate);
			
			//Get semester code for minimum semester sequence of user semester group
			TransferNORInPSTBean minSemesterData=new TransferNORInPSTBean(programId,semesterCode);
			String minRegisterSemesterCode=registrationFunction.getMinimumSemester(minSemesterData);
			//System.out.println("Minimum semester code:"+minRegisterSemesterCode);
			
			//pick up program course key for minimum semester
			TransferNORInPSTBean minimumCourseKeyData=new TransferNORInPSTBean(programId,branchId,specializationId,minRegisterSemesterCode);
			String minProgramCourseKey=registrationFunction.getProgramCourseKey(minimumCourseKeyData);
			//System.out.println("Minimum course key data:"+minProgramCourseKey);

			//pick up max attempt number for program
			int maxAttemptAllowed=registrationFunction.maximumAttempNumberAllowed(new TransferNORInPSTBean(programId));
			//System.out.println(maxAttemptAllowed);
			
			TransferNORInPSTBean studentProgramData=new TransferNORInPSTBean(entityId,programId,branchId,
					specializationId,semesterCode,semesterStartDate,semesterEndDate,programCourseKey,CRConstant.ACTIVE_STATUS,CRConstant.LOAD_REGULAR_STUDENT);
			
			//pick up list of students from student program
			studentProgramList=(List<TransferNORInPSTBean>)sqlMapClient.queryForList("TransferNORInPSTBean.getListOfStudentToProcess", studentProgramData);
			
//			System.out.println("Total student: "+studentProgramList.size());
			//countList.add(studentProgramList.size());
			
			for(TransferNORInPSTBean studentProgram:studentProgramList){
				//System.out.println("coming before list"+studentProgram.getRollNumber());
				try{
				
				String rollNumber=studentProgram.getRollNumber();
				int attemptNumber=studentProgram.getAttemptNumber();
//				System.out.println("Attempt Number "+attemptNumber+" for "+rollNumber);
				String registrationProgramCourseKey=registerProgramCourseKey;
				String registrationSemStartDate=registerSemesterStartDate;
				String registrationSemEndDate=registerSemesterEndDate;
				String registrationDueDate=registerDueDate;
				String registrationSemester=registerSemester;
				
				errorLogs.setEnrollmentNumber(studentProgram.getEnrollmentNumber());
				errorLogs.setStudentId(studentProgram.getStudentId());
				errorLogs.setStudentName(new StudentTrackingFunction().getFullName(studentProgram.getStudentFirstName(),
						studentProgram.getStudentMiddleName(),studentProgram.getStudentLastName()));
				
				//If status of student is PAS or FAL, this code of block executes.
				//In case of pass, if group are same then atte
				if(studentProgram.getStatusInSemester().equalsIgnoreCase(CRConstant.STATUS_PASS)||
						studentProgram.getStatusInSemester().equalsIgnoreCase(CRConstant.STATUS_FAIL)){
			
							if(studentProgram.getStatusInSemester().equalsIgnoreCase(CRConstant.STATUS_PASS)){
								
								if(!checkGroup){
									attemptNumber=1;
//									System.out.println("Attempt Number "+attemptNumber+" for "+rollNumber);
								}//If checkgroup ends
//								System.out.println(registerSemesterStartDate+"before setting register due date");
//								System.out.println("register due date for pass: "+registerDueDate);
							}//If PAS closed
					
							if(studentProgram.getStatusInSemester().equalsIgnoreCase(CRConstant.STATUS_FAIL)){
								//System.out.println(maxAttemptAllowed+" and "+attemptNumber);
								
										if(attemptNumber<maxAttemptAllowed){
											
											attemptNumber=attemptNumber+1;
											
											//System.out.println("Attempt number for fail: "+attemptNumber);					
										PreviousSemesterDetail minimumSemesterData=new PreviousSemesterDetail(rollNumber,entityId,
												minProgramCourseKey);
										List<PreviousSemesterDetail> minimumSemesterResult=registrationFunction.getPreviousSessionDate(minimumSemesterData);
											for(PreviousSemesterDetail minSemesterdetail:minimumSemesterResult){
												//System.out.println("coming inside ths ");
												registrationSemStartDate=minSemesterdetail.getPreviousSemesterStartDate();
												registrationSemEndDate=minSemesterdetail.getPreviousSemesterEndDate();
												//System.out.println(registrationSemEndDate+" abc "+registrationSemStartDate);
											}//Previous detail loop ends
										
										registrationSemester=minRegisterSemesterCode;
										
										TransferNORInPSTBean registrationDateForFail=new TransferNORInPSTBean(minProgramCourseKey,
												registrationSemStartDate,registrationSemEndDate);
										//System.out.println("register due date for fail:"+registrationFunction.getRegisterDueDate(registrationDateForFail));
										registrationDueDate=registrationFunction.getNextYear(registrationFunction.getRegisterDueDate(registrationDateForFail));
										
										registrationSemStartDate=registrationFunction.getNextYear(registrationSemStartDate);
										
										registrationSemEndDate=registrationFunction.getNextYear(registrationSemEndDate);
										
										//System.out.println("register due date for fail:"+registrationDueDate);
										
										registrationProgramCourseKey=minProgramCourseKey;
										}//if attempt number ends
										else{
											attemptNumber=00;
											registrationSemester="NA";
											registrationDueDate="1111-11-11";
											registrationSemStartDate="1111-11-11";
											registrationSemEndDate="1111-11-11";
										}//else attempt number ends
							}//if Fail ends
					TransferNORInPSTBean passOrFailPSTData=new TransferNORInPSTBean( entityId,  programId,
							 branchId,  specializationId,  semesterCode,
							 semesterStartDate,  semesterEndDate,
							 sessionStartDate,sessionEndDate,
							 programCourseKey,  studentProgram.getStudentId(),
							 studentProgram.getEnrollmentNumber(),  studentProgram.getRollNumber(),
							 studentProgram.getStudentFirstName(),  studentProgram.getStudentMiddleName(),
							 studentProgram.getStudentLastName(),  studentProgram.getFatherFirstName(),
							 studentProgram.getFatherMiddleName(),  studentProgram.getFatherLastName(),
							 studentProgram.getMotherFirstName(),  studentProgram.getMotherMiddleName(),
							 studentProgram.getMotherLastName(),  studentProgram.getDateOfBirth(),  
							 studentProgram.getCategory(),
							 studentProgram.getGender(),  studentProgram.getPrimaryEmailId(),
							 studentProgram.getStatusInSemester(),attemptNumber,
							 registrationProgramCourseKey, registrationSemester,
							 registrationSemStartDate, registrationSemEndDate,
							 registrationDueDate,checkGroup,
							maxAttemptAllowed, CRConstant.NORMAL_MODE,CRConstant.YET_TO_REGISTER,CRConstant.LOAD_REGULAR_STUDENT,
							 creatorId,activityId);
//					System.out.println("Coming till here");
					preStagingTransactionFunction.executeQueryForPreStaging(passOrFailPSTData);
					processedStudent++;
								
										
				}//IF PAS for FAL ends
				
				//If status of student is REM, then probable entries will be calculated
				if(studentProgram.getStatusInSemester().equalsIgnoreCase(CRConstant.STATUS_REMEDIAL)){
						String probaleSemester=minRegisterSemesterCode;
						String probableSemesterStartDate="";
						String probableSemesterEndDate="";
						int probableAttemptNumber=attemptNumber;
						String probableRegisterDueDate="";
						
						if(!checkGroup){
							attemptNumber=1;
						}
						
						if(attemptNumber<maxAttemptAllowed){
							probableAttemptNumber=attemptNumber+1;
							//System.out.println("Attempt number for fail: ");	
							
						PreviousSemesterDetail minimumSemesterData=new PreviousSemesterDetail(rollNumber,entityId,
								minProgramCourseKey);
						List<PreviousSemesterDetail> minimumSemesterResult=registrationFunction.getPreviousSessionDate(minimumSemesterData);
							for(PreviousSemesterDetail minSemesterdetail:minimumSemesterResult){
								//System.out.println("coming inside ths ");
								probableSemesterStartDate=minSemesterdetail.getPreviousSemesterStartDate();
								probableSemesterEndDate=minSemesterdetail.getPreviousSemesterEndDate();
								//System.out.println(registrationSemEndDate+" abc "+registrationSemStartDate);
							}//Previous detail loop ends REM
						
							
						
						TransferNORInPSTBean registrationDateForFail=new TransferNORInPSTBean(minProgramCourseKey,
								probableSemesterStartDate,probableSemesterEndDate);
						//System.out.println("register due date for REM:"+registrationFunction.getRegisterDueDate(registrationDateForFail));
						probableRegisterDueDate=registrationFunction.getNextYear(registrationFunction.getRegisterDueDate(registrationDateForFail));
						
						probableSemesterStartDate=registrationFunction.getNextYear(probableSemesterStartDate);
						
						probableSemesterEndDate=registrationFunction.getNextYear(probableSemesterEndDate);
						//System.out.println("register due date for fail:"+registrationDueDate);
						
						}//if attempt number ends REM
						else{
							probableAttemptNumber=00;
							probaleSemester="NA";
							probableRegisterDueDate="1111-11-11";
							probableSemesterStartDate="1111-11-11";
							probableSemesterEndDate="1111-11-11";
						}//else attempt number endsfor REM
						
						TransferNORInPSTBean remedialPSTData=new TransferNORInPSTBean( entityId,  programId,
								 branchId,  specializationId,  semesterCode,
								 semesterStartDate,  semesterEndDate,
								 sessionStartDate,sessionEndDate,
								 programCourseKey,  studentProgram.getStudentId(),
								 studentProgram.getEnrollmentNumber(),  studentProgram.getRollNumber(),
								 studentProgram.getStudentFirstName(),  studentProgram.getStudentMiddleName(),
								 studentProgram.getStudentLastName(),  studentProgram.getFatherFirstName(),
								 studentProgram.getFatherMiddleName(),  studentProgram.getFatherLastName(),
								 studentProgram.getMotherFirstName(),  studentProgram.getMotherMiddleName(),
								 studentProgram.getMotherLastName(),  studentProgram.getDateOfBirth(),  
								 studentProgram.getCategory(),
								 studentProgram.getGender(),  studentProgram.getPrimaryEmailId(),
								 studentProgram.getStatusInSemester(),attemptNumber,
								 registrationProgramCourseKey, registrationSemester,
								 registrationSemStartDate, registrationSemEndDate,
								 registrationDueDate,checkGroup,
								maxAttemptAllowed, CRConstant.NORMAL_MODE,CRConstant.YET_TO_REGISTER,CRConstant.LOAD_REGULAR_STUDENT,
								probaleSemester,probableRegisterDueDate,
								probableSemesterStartDate,probableSemesterEndDate,probableAttemptNumber,
								 creatorId,activityId);
						preStagingTransactionFunction.executeQueryForRemedialPreStaging(remedialPSTData);
						processedStudent++;
									
				}//REM  if ends
				
				}catch(Exception listException){
					System.out.println("Coming here ");
					System.out.println("Values in Exception Value:");
					errorLogs.setReasonCode("DBI");
					errorLogs.setDescription("Unknown issue");
				
					errorLogs.setProcessFlag(CRConstant.ERROR_STATUS);
					
					recordsFailed++;
					System.out.println("Coming for inserting in student error log");
					sqlMapClient.insert("studentTrackingAndLogs.insertStudentErrorLog", errorLogs);
					
//					System.out.println("Exception in Normal Process"+listException.getMessage());
				}
			}//Loop ends
			
			
		//System.out.println("Coming till last");
			
		}catch(Exception e){
			System.out.println("Exception in normal process"+e);
			errorLogs.setReasonCode("DBI");
			errorLogs.setDescription("Unknown issue");
		
			errorLogs.setProcessFlag(CRConstant.ERROR_STATUS);
			
			rejectedValue=actualRecords-(processedStudent+recordsFailed);
			try{
			sqlMapClient.insert("studentTrackingAndLogs.insertStudentErrorLog", errorLogs);
		}catch(Exception studentTracking){
			System.out.println("Exception inside loop and inseting student error logs:"+studentTracking);
		}
			logger.info("Exception in transfer to PST"+e.getMessage());
		}
		finally{
			
			actualRecords=studentProgramList.size();
//			String processFlag=CRConstant.INACTIVE_STATUS;
			
//			System.out.println(actualRecords+"="+processedStudent);
			if(actualRecords==processedStudent && actualRecords!=0){
				System.out.println("Coming here");
//				processFlag=CRConstant.COMPLETE_STATUS;
				processedFlag=true;
			}
//			errorLogs.setActualRecord(actualRecords);
//			errorLogs.setProcessRecord(processedStudent);
//			errorLogs.setFailrecord(recordsFailed+rejectedValue);
//			errorLogs.setProcessFlag(processFlag);
//			try{
//			int x=(Integer)sqlMapClient.insert("studentTrackingAndLogs.updateBatchErrorLogs", errorLogs);
//			}catch(Exception e1){
//				//System.out.println("Exception inside final block:"+e1.getMessage());
//				countList=new CountProcessRecorList(actualRecords,processedStudent,rejectedValue,recordsFailed,processedFlag);
//			}
			countList=new CountProcessRecorList(actualRecords,processedStudent,rejectedValue,recordsFailed,processedFlag);
//			System.out.println(countList.getTotalRecords()+" "+countList.getCorrectProcessed()+" "+countList.getRejectedProcessed());
		}
		return countList;
	}


}
